package cn.poka.util;

public class RFIDProtocol {


	/** 帧头(两个字节) */
	private static String head;

	/**  帧长度(两个字节) */
	private static String len;

	/**  帧类型(一个字节) */
	private static String type;

	/** 访问密码 (四个字节)*/
	private static String ap;

	/** pc */
	private static String pc;

	/** epc() */
	private static String epc;

	/** mb用户需要写入数据的bank号（01：epc区；03：user区） */
	private static String mb;

	/** sa起始地址(两个字节) */
	private static String sa;

	/** dl需写入的数据长度(两个字节) */
	private static String dl;

	/** epc区data需写入的数据 (12个字节)*/
	private static String epcData;

	/** user区data需写入的数据(16个字节)*/
	private static String userData;

	private static String data;

	/** 验证码 (一个字节   每帧数据所有字节（除去帧头和帧尾）异或)*/
	private static String crc;

	/** 帧尾 */
	private static String end;

	/**
	 * rfid报文数据初始化
	 */
	public static void init(){
		head = "A55A";
		len = "0000";
		type = "00";
		ap = "00000000";
		pc = "0000";
		epc = "000000000000000000000000";
		mb = "01";
		sa = "0000";
		dl = "0000";
		epcData = "00112233445566778899AABB";
		userData = "00112233445566778899AABB00112233";
		data = "0000";
		crc = "00";
		end = "0D0A";
	}

	/**
	 * 封装rfid写数据报文
	 * @return
	 */
	public static String componentWriteRfidMessage(){
		StringBuffer sb = new StringBuffer();
		sb.append(head);
		sb.append(len);
		sb.append(type);
		sb.append(ap);
		sb.append(pc);
		sb.append(epc);
		sb.append(mb);
		sb.append(sa);
		sb.append(dl);
		if(mb.equals("01")){
			sb.append(epcData);
		}else if(mb.equals("03")){
			sb.append(userData);
		}
		sb.append(crc);
		sb.append(end);

		System.out.println("sb:" + sb.toString());
		changeMessageLen(sb);
		System.out.println("sb:" + sb.toString());

		changeMessageCrc(sb);
		System.out.println("sb:" + sb.toString());

		return sb.toString();
	}

	/**
	 * 封装Rfid读数据报文
	 * @return
	 */
	public static String componentReadRfidMessage(){
		StringBuffer sb = new StringBuffer();
		sb.append(head);
		sb.append(len);
		sb.append(type);
		sb.append(ap);
		sb.append(pc);
		sb.append(epc);
		sb.append(mb);
		sb.append(sa);
		sb.append(dl);
		sb.append(crc);
		sb.append(end);

		System.out.println("sb:" + sb.toString());
		changeMessageLen(sb);
		System.out.println("sb:" + sb.toString());

		changeMessageCrc(sb);
		System.out.println("sb:" + sb.toString());

		return sb.toString();
	}

	public static String componentSingleReadMessage(){
		StringBuffer sb = new StringBuffer();
		sb.append(head);
		sb.append(len);
		sb.append(type);
		sb.append(data);
		sb.append(crc);
		sb.append(end);

		changeMessageLen(sb);

		changeMessageCrc(sb);

		return sb.toString();
	}

	public static String resolverSingleReadMessage(String message){
		System.out.println("==Message:" + message + "   " + message.length());
		if(message != null && !message.equals("") && message.length() == 50){
			String type = message.substring(8,10);
			if(type != null && type.equals("81")){
				System.out.println("=========resolverRfidReadReplyMessage=========================message:" + message);
				int index = message.indexOf("0D0A");
				System.out.println("index==:" + index);
				String result = message.substring(14,index - 8);
				System.out.println("==result:" + result);
				return result;
			}
			return "";
		}else{
			return null;
		}
	}

	/**
	 * 解析rfid写应答报文，获取应答报文flag位是否为"01"，如果是表示写成功，否则表示写失败
	 * @param message
	 * @return
	 */
	public static boolean resolverRfidWriteReplyMessage(String message){
		if(message != null && !message.equals("") && message.length() == 20){
			String type = message.substring(8,10);
			if(type != null && type.equals("87")){
				String flag = message.substring(10, 12);
				if(flag != null && flag.equals("01")){
					return true;
				}
			}else{
				return false;
			}
		}
		return false;
	}

	/**
	 * crc8验证
	 * @param message
	 * @return
	 */
	public static String getCrc8(String message){
		byte[] buf = hexStringToBytes(message);
		//byte crc = buf[0];
		byte crc = 0x00;
		for (int i = 0; i < buf.length; i++) {
			System.out.print(Integer.toHexString((buf[i] & 0x000000FF) | 0xFFFFFF00).substring(6) + " ");
			crc = (byte)(crc^buf[i]);
			for(int j=0;j< 8 ;j++){
				int result = (int)(crc & 0x80);
				if(result > 0){
					crc = (byte)((crc << 1)^0x8D);
				}else{
					crc <<= 1;
				}
			}
		}

		//int result = (int)(crc & 0xFF);

		crc = (byte)(crc & 0xFF);

		return Integer.toHexString((crc & 0x000000FF) | 0xFFFFFF00).substring(6).toUpperCase();
	}

	/**
	 * 解析rfid读应答报文，首先获取应答报文的flag位是否为“01”，如果是，进一步获取应答的数据，然后返回
	 * @param message
	 * @return
	 */
	public static String resolverRfidReadReplyMessage(String message){
		String flag = message.substring(10,12);
		if(flag != null && flag.equals("01")){
			System.out.println("=========resolverRfidReadReplyMessage=========================message:" + message);
			int index = message.indexOf("0D0A");
			System.out.println("index==:" + index);
			return message.substring(18,index - 2);
		}
		return "";
	}

	/**
	 * 获取报文的验证码，然后更新报文的验证码
	 * @param sb协议报文
	 */
	private static void changeMessageCrc(StringBuffer sb){
		byte[] buf = hexStringToBytes(sb.toString());
		System.out.println(buf.length);
		byte crc = buf[2];
		int len = buf.length - 3;
		for (int i = 3; i < len; i++) {
			crc = (byte)(crc^buf[i]);
		}
		String crcStr = byteToHexString(crc);
		System.out.println("crcStr:" + crcStr);
		sb.replace(sb.length() - 6, sb.length() - 4, crcStr);
	}

	public static String getCrc(String message){
		byte[] buf = hexStringToBytes(message);
		byte crc = buf[0];
		for (int i = 1; i < buf.length; i++) {
			crc = (byte)(crc^buf[i]);
		}
		return byteToHexString(crc);
	}



	/**
	 * 获取报文的长度，然后更新报文的长度
	 * @param sb 协议报文
	 */
	private static void changeMessageLen(StringBuffer sb){
		int length = sb.toString().length() / 2;
		System.out.println("length:" + length);
		String lenStr = byteToHexString((byte)length);
		System.out.println("lenStr:" + lenStr);
		sb.replace(6, 8, lenStr);
	}

	/**
	 * 将字节转换为16进制的字符串
	 * @param len
	 * @return
	 */
	public static String byteToHexString(byte len){
		return Integer.toHexString((len & 0x000000FF) | 0xFFFFFF00).substring(6).toUpperCase();
	}

	/**
	 * 把16进制字符串转换为byte数组
	 */
	public static byte[] hexStringToBytes(String hexString) {
		if (hexString == null || hexString.equals("")) {
			return null;
		}
		hexString = hexString.toUpperCase();    //如果是大写形式
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
		}
		return d;
	}

	public static String byteToHexString(byte[] buf){
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < buf.length; i++) {
			String bufTemp = Integer.toHexString((buf[i] & 0x000000FF) | 0xFFFFFF00).substring(6).toUpperCase();
			sb.append(bufTemp);
		}
		return sb.toString();
	}

	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}

	public static void main(String[] args) {
		String str = "000000A521B1000100F000000000000000000000000000000000000000BB4C82A5E31BDACBE3";
		String crcCode = getCrc(str.substring(0,str.length() - 2));
		System.out.println("crcCode:" + crcCode);
	}



	//--------------------------------------------------------

	public static String getHead() {
		return head;
	}

	public static void setHead(String head) {
		RFIDProtocol.head = head;
	}

	public static String getLen() {
		return len;
	}

	public static void setLen(String len) {
		RFIDProtocol.len = len;
	}

	public static String getType() {
		return type;
	}

	public static void setType(String type) {
		RFIDProtocol.type = type;
	}

	public static String getAp() {
		return ap;
	}

	public static void setAp(String ap) {
		RFIDProtocol.ap = ap;
	}

	public static String getEpc() {
		return epc;
	}

	public static void setEpc(String epc) {
		RFIDProtocol.epc = epc;
	}

	public static String getMb() {
		return mb;
	}

	public static void setMb(String mb) {
		RFIDProtocol.mb = mb;
	}

	public static String getSa() {
		return sa;
	}

	public static void setSa(String sa) {
		RFIDProtocol.sa = sa;
	}

	public static String getDl() {
		return dl;
	}

	public static void setDl(String dl) {
		RFIDProtocol.dl = dl;
	}

	public static String getEpcData() {
		return epcData;
	}

	public static void setEpcData(String epcData) {
		RFIDProtocol.epcData = epcData;
	}

	public static String getUserData() {
		return userData;
	}

	public static void setUserData(String userData) {
		RFIDProtocol.userData = userData;
	}

	public static String getCrc() {
		return crc;
	}

	public static void setCrc(String crc) {
		RFIDProtocol.crc = crc;
	}

	public static String getEnd() {
		return end;
	}

	public static void setEnd(String end) {
		RFIDProtocol.end = end;
	}

	public static String getPc() {
		return pc;
	}

	public static void setPc(String pc) {
		RFIDProtocol.pc = pc;
	}

	public static String getData() {
		return data;
	}

	public static void setData(String data) {
		RFIDProtocol.data = data;
	}

}
